<template>
  <div class="page-container">
    <a-card class="token-generator">
      <h1>Token 生成器</h1>
      <p class="description">使用您想要的字母、大写或小写字母、数字和/或符号生成随机的字符串。</p>

      <div class="options">
        <div class="option-row">
          <label class="option">
            <span>大写 (ABC...)</span>
            <a-switch v-model:checked="options.uppercase" />
          </label>

          <label class="option">
            <span>数字 (123...)</span>
            <a-switch v-model:checked="options.numbers" />
          </label>
        </div>

        <div class="option-row">
          <label class="option">
            <span>小写 (abc...)</span>
            <a-switch v-model:checked="options.lowercase" />
          </label>

          <label class="option">
            <span>符号 (!-...)</span>
            <a-switch v-model:checked="options.symbols" />
          </label>
        </div>

        <div class="length-slider">
          <span>长度 ({{ options.length }})</span>
          <a-slider v-model:value="options.length" :min="1" :max="128" :step="1" />
        </div>
      </div>

      <div class="result">
        <a-input :value="generatedToken" readonly :rows="3" class="token-input" />
      </div>

      <div class="actions">
        <a-button type="primary" @click="copyToken"> 复制 </a-button>
        <a-button @click="generateToken"> 刷新 </a-button>
      </div>
    </a-card>
  </div>
</template>

<script setup>
import { ref, reactive, onMounted, watch } from 'vue'
import { message } from 'ant-design-vue'

// 定义字符集
const CHARS = {
  uppercase: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
  lowercase: 'abcdefghijklmnopqrstuvwxyz',
  numbers: '0123456789',
  symbols: '!@#$%^&*()_+-=[]{}|;:,.<>?'
}

// 配置选项
const options = reactive({
  uppercase: true,
  lowercase: true,
  numbers: true,
  symbols: false,
  length: 64
})

const generatedToken = ref('')

// 监听配置变化，自动更新token
watch(
  options,
  () => {
    generateToken()
  },
  { deep: true }
)

// 生成随机token
const generateToken = () => {
  let chars = ''
  if (options.uppercase) chars += CHARS.uppercase
  if (options.lowercase) chars += CHARS.lowercase
  if (options.numbers) chars += CHARS.numbers
  if (options.symbols) chars += CHARS.symbols

  if (!chars) {
    message.warning('请至少选择一种字符类型')
    return
  }

  let result = ''
  const charsLength = chars.length
  for (let i = 0; i < options.length; i++) {
    result += chars.charAt(Math.floor(Math.random() * charsLength))
  }
  generatedToken.value = result
}

// 复制到剪贴板
const copyToken = async () => {
  if (!generatedToken.value) {
    message.warning('请先生成Token')
    return
  }

  try {
    await navigator.clipboard.writeText(generatedToken.value)
    message.success('复制成功')
  } catch (err) {
    message.error('复制失败')
  }
}

// 组件挂载时生成初始token
onMounted(() => {
  generateToken()
})
</script>

<style scoped>
.page-container {
  min-height: 100vh;
  padding: 24px;
  background: #f0f2f5;
}

.token-generator {
  max-width: 800px;
  margin: 0 auto;
}

.token-generator :deep(.ant-card-body) {
  padding: 24px;
}

h1 {
  margin-top: 0;
  margin-bottom: 16px;
  font-size: 24px;
  font-weight: 500;
}

.description {
  color: #595959;
  margin-bottom: 20px;
}

.options {
  background: #fafafa;
  padding: 20px;
  border-radius: 8px;
  margin-bottom: 20px;
  border: 1px solid #f0f0f0;
}

.option-row {
  display: flex;
  justify-content: space-between;
  margin-bottom: 15px;
  padding: 0 12px;
}

.option {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 45%;
  color: #262626;
}

.length-slider {
  margin-top: 20px;
  padding: 0 12px;
}

.result {
  margin: 20px 0;
}

.token-input {
  background: #fafafa;
  color: #333;
  border: 1px solid #f0f0f0;
  padding: 15px;
  border-radius: 8px;
  width: 100%;
  min-height: 100px;
  resize: none;
  font-family: monospace;
}

.actions {
  display: flex;
  gap: 10px;
  justify-content: center;
  margin-top: 24px;
}
</style>
